﻿using System;
using System.Collections.Generic;
using System.Linq;
using Hybrid;

namespace DSS.HybridClasses
{
    public class Point
    {
        public int IdInAdjencyMatrix { get; set; }
        public bool IsVariety { get; set; }
        public bool IsPoint { get; set; }
        public String Color { get; set; }
        public int PreferenceId { get; set; }//ай-ди множества
        public int Level { get; set; }//сумма нмеров в таблице(для упорядочения по парето)
        public int FinalLevel { get; set; }//итоговый уровень при разборе графа
        public List<Gradation> ListOfGradations = new List<Gradation>();//список градаций

        public Point CopyPointExcepLastGradation()
        {
            var r = new Point();
            foreach (var gr in ListOfGradations)
            {
                r.ListOfGradations.Add(new Gradation { CriteriaNum = gr.CriteriaNum, NumInGrid = gr.NumInGrid, Value = gr.Value });
            }
            r.ListOfGradations.RemoveAt(r.ListOfGradations.Count - 1);//-1
            return r;
        }
        public Point FullCopy()
        {
            var r = new Point();
            foreach (var gr in ListOfGradations)
            {
                r.ListOfGradations.Add(new Gradation { CriteriaNum = gr.CriteriaNum, NumInGrid = gr.NumInGrid, Value = gr.Value });
            }
            r.IdInAdjencyMatrix = IdInAdjencyMatrix;
            r.IsPoint = IsPoint;
            r.IsVariety = IsVariety;
            r.Level = Level;
            r.PreferenceId = PreferenceId;
            return r;
        }
   

        public void SetLevel()//задать уровень для парето
        {
            var l = ListOfGradations.Sum(gr => gr.NumInGrid);
            Level = l;
        }

        public static bool DominatingOnPareto(Point p1, Point p2)
        {
            bool strictly = false;//строгое неравенство
            for (byte i = 0; i < p1.ListOfGradations.Count; ++i)
            {
                if (p1.ListOfGradations[i].NumInGrid >= p2.ListOfGradations[i].NumInGrid)//лучше или равно
                {
                    if (p1.ListOfGradations[i].NumInGrid > p2.ListOfGradations[i].NumInGrid)//1 обязательно лучше
                        strictly = true;
                }
                else
                    return false;
            }
            return strictly;
        }


        public static bool DominatingOnPodvinsky(Point p1, Point p2, Grid g)
        {
            byte diferences = 0;//кол-во разных критериев
            var firstFounded = false;//первое расхождение
            var r = false;//результат
            var gradations = new int[4];
            var first = 0;
            for (int i = p1.ListOfGradations.Count - 1; i >= 0; --i)//все в обратной последовательности
                if (p1.ListOfGradations[i].NumInGrid != p2.ListOfGradations[i].NumInGrid)
                {
                    ++diferences;//отличия по градациям
                        if ((!firstFounded) 
                            && (p1.ListOfGradations[i].NumInGrid > p2.ListOfGradations[i].NumInGrid))//более важный лучше
                        {
                            gradations[0] = p1.ListOfGradations[i].NumInGrid;
                            gradations[1] = p2.ListOfGradations[i].NumInGrid;
                            firstFounded = true;
                            first=i;
                        }
                        if (Grid.ListOfCriterias[p1.ListOfGradations[first].CriteriaNum].ListOfGradations.Count == Grid.ListOfCriterias[p1.ListOfGradations[i].CriteriaNum].ListOfGradations.Count)
                        if ((firstFounded)
                            && (p1.ListOfGradations[i].NumInGrid < p2.ListOfGradations[i].NumInGrid))//менее важный хуже на 1
                        {
                            gradations[2] = p1.ListOfGradations[i].NumInGrid;
                            gradations[3] = p2.ListOfGradations[i].NumInGrid;
                            r = true;
                        }
                }
            return (diferences == 2) && (r) && (firstFounded) && (gradations[0] == gradations[3]) && (gradations[2] == gradations[1]);
        }

        public Point()
        {
            IsPoint = true;
            IsVariety = false;
        }
        public static bool operator ==(Point p1, Point p2)
        {
            if(p1==null||p2==null)
                throw new ArgumentNullException("one of points is null");
            for (byte i = 0; i < p1.ListOfGradations.Count; ++i)
            {
                if (!((p1.ListOfGradations[i].CriteriaNum == p2.ListOfGradations[i].CriteriaNum) &&
                    (p1.ListOfGradations[i].NumInGrid == p2.ListOfGradations[i].NumInGrid)))
                    return false;
            }
            return true;
        }
        public static bool operator !=(Point p1, Point p2)
        {
            return (!(p1 == p2));
        }
    }
}
